package co.fitstart.entity.courseware.fitnessgroup;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.OrderBy;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.Where;
import com.alibaba.fastjson.annotation.JSONField;
import com.demo2do.core.utils.DateFormatUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import co.fitstart.entity.course.round.CourseRound;
import co.fitstart.entity.courseware.dietary.DietaryProgram;
import co.fitstart.entity.courseware.dietary.DietaryProgramTemplate;
import co.fitstart.entity.utils.DateUtils;

/**
 * 
 * @author mohanlan
 *
 */
@Entity
@Table(name = "batch_courseware")
@JsonIgnoreProperties(value={"hibernate_lazy_initializer","handler","fieldHandler"})
public class BatchCourseware {
    
    @Id
    @GeneratedValue
    private Long id;
    
    private String name;
    
    private int sorting;
    
    /** 链接 */
    private String webLink;
    
    /** 教练Tips */
    @Type(type = "text")
    @JSONField(serialize = false)
    private String coachTips;
    
    /** 课件周期类型 */
    @Enumerated(EnumType.ORDINAL)
    private BatchCoursewareType type;
    
    /** 所属课程 */
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    private CourseRound courseRound;
    
    @Enumerated(EnumType.ORDINAL)
    private RoundwareStatus roundwareStatus;
    
    @Enumerated(EnumType.ORDINAL)
    private CoursewareEditStatus editStatus;
    
    /** 周计划第一天 */
    @org.hibernate.annotations.Type(type = "date")
    private Date begin;
    
    /** 周计划最后一天 */
    @org.hibernate.annotations.Type(type = "date")
    private Date end;
    
    /** 周计划发送时间 */
    private Date linkTime;
    
    /** 饮食计划 早中晚餐*/
    @OneToMany(mappedBy = "batch", fetch = FetchType.LAZY)
    @Where(clause = "is_disabled = 0")
    @OrderBy(clause = "type ASC")
    @MapKey(name = "type")
    @JSONField(serialize = false)
    @JsonIgnore
    private Map<String, DietaryProgram> dietaryPrograms;
    
    @OneToMany(mappedBy = "batch", fetch = FetchType.LAZY)
    @Where(clause = "is_disabled = 0")
    @OrderBy(clause = "sorting ASC")
    @JSONField(serialize = false)
    @JsonIgnore
    private List<DailyCourseware>  dailyCoursewares;
    
    @Column(name = "is_disabled")
    private boolean disabled;
    
    /**
     * The default constructor
     */
    public BatchCourseware() {
    }

    public BatchCourseware(CourseRound courseRound, int week, Date begin, Date end) {
        this.name = "第" + week + "周";
        this.sorting = week;
        this.type = BatchCoursewareType.WEEKLY;
        this.courseRound = courseRound;
        this.roundwareStatus = RoundwareStatus.GROUPED;
        this.editStatus = CoursewareEditStatus.PREPARE;
        this.begin = begin;
        this.end = end;
        this.disabled = false;
    }
    
    /**
     * 
     * @param batchCoursewareTemplate
     * @param courseRound
     */
    public BatchCourseware(BatchCoursewareTemplate batchCoursewareTemplate, CourseRound courseRound) {
        this.name = batchCoursewareTemplate.getName();
        this.sorting = batchCoursewareTemplate.getSorting();
        this.type = batchCoursewareTemplate.getType();
        this.courseRound = courseRound;
        this.roundwareStatus = RoundwareStatus.GROUPED;
        this.editStatus = CoursewareEditStatus.PREPARE; 
        this.disabled = false;
        
    }
    
    /**
     * 
     * @param batchCoursewareTemplate
     * @return
     */
    public BatchCourseware edit(BatchCoursewareTemplate batchCoursewareTemplate) {
        this.name = batchCoursewareTemplate.getName();
        this.roundwareStatus = RoundwareStatus.GROUPED;
        this.editStatus = CoursewareEditStatus.PREPARE;
        return this;
    }

    /**
     * 
     * @param begin
     * @param end
     * @return
     */
    public BatchCourseware edit(Date begin, Date end) {
        this.begin = begin;
        this.end = end;
        return this;
    }
    
    /**
     * 
     * @param end
     * @return
     */
    public BatchCourseware editEnd(Date end) {
        this.end = end;
        return this;
    }
    
    /**
     * 
     * @param template
     * @return
     */
    public BatchCourseware addDietaryProgram(String name, DietaryProgramTemplate template) {
        if(template != null) {
            if(MapUtils.isEmpty(dietaryPrograms)) {
                this.dietaryPrograms = new HashMap<String, DietaryProgram>();
            }
            this.dietaryPrograms.put(name, new DietaryProgram(template, this));
        }
        
        return this;
    }
    
    /**
     * 
     * @param roundwareStatus
     * @return
     */
    public BatchCourseware editRoundwareStatus(RoundwareStatus roundwareStatus) {
        this.roundwareStatus = roundwareStatus;
        return this;
    }
    
    /**
     * 
     * @return
     */
    public BatchCourseware editBatch() {
        this.roundwareStatus = RoundwareStatus.READY;
        this.editStatus = CoursewareEditStatus.EDITED;
        return this;
    }
    
    /**
     * 
     * @param editStatus
     * @return
     */
    public BatchCourseware editCoursewareEditStatus(CoursewareEditStatus editStatus) {
        this.editStatus = editStatus;
        return this;
    }
    
    /**
     * 
     * @param webLink
     * @param tips
     * @return
     */
    public BatchCourseware link(String webLink, String tips) {
        this.webLink = webLink;
        if(StringUtils.isNotEmpty(tips)) {
            this.coachTips = tips;
        }
        this.roundwareStatus = RoundwareStatus.FINISH;
        this.editStatus = CoursewareEditStatus.GENERATED;
        this.linkTime = new Date();
        return this;
    }
    
    /**
     * 
     * @return
     */
    public BatchCourseware link(String tips) {
        if(StringUtils.isNotEmpty(tips)) {
            this.coachTips = tips;
        }
        this.roundwareStatus = RoundwareStatus.FINISH;
        this.editStatus = CoursewareEditStatus.GENERATED;
        this.linkTime = new Date();
        return this;
    }
    
    /**
     * 
     * @return
     */
    public BatchCourseware saveAll() {
        this.editStatus = CoursewareEditStatus.EDITED;
        return this;
    }

    /**
     * 
     * @return
     */
    public boolean isThisWeek() {
        if(begin != null && end != null) {
            Date today = DateUtils.parseDate(DateFormatUtils.format(new Date(), "yyyy-MM-dd"), "yyyy-MM-dd");
            
            if(!begin.after(today) && !end.before(today)) {
                return true;
            }
        }
        
        return false;
    }

    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @return the sorting
     */
    public int getSorting() {
        return sorting;
    }

    /**
     * @return the webLink
     */
    public String getWebLink() {
        return webLink;
    }

    /**
     * @return the coachTips
     */
    public String getCoachTips() {
        return coachTips;
    }

    /**
     * @return the type
     */
    public BatchCoursewareType getType() {
        return type;
    }

    /**
     * @return the courseRound
     */
    public CourseRound getCourseRound() {
        return courseRound;
    }

    /**
     * @return the roundwareStatus
     */
    public RoundwareStatus getRoundwareStatus() {
        return roundwareStatus;
    }

    /**
     * @return the editStatus
     */
    public CoursewareEditStatus getEditStatus() {
        return editStatus;
    }

    /**
     * @return the begin
     */
    public Date getBegin() {
        return begin;
    }

    /**
     * @return the end
     */
    public Date getEnd() {
        return end;
    }

    /**
     * @return the linkTime
     */
    public Date getLinkTime() {
        return linkTime;
    }

    /**
     * @return the dietaryPrograms
     */
    public Map<String, DietaryProgram> getDietaryPrograms() {
        return dietaryPrograms;
    }

    /**
     * @return the dailyCoursewares
     */
    public List<DailyCourseware> getDailyCoursewares() {
        return dailyCoursewares;
    }

    /**
     * @return the disabled
     */
    public boolean isDisabled() {
        return disabled;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @param sorting the sorting to set
     */
    public void setSorting(int sorting) {
        this.sorting = sorting;
    }

    /**
     * @param webLink the webLink to set
     */
    public void setWebLink(String webLink) {
        this.webLink = webLink;
    }

    /**
     * @param coachTips the coachTips to set
     */
    public void setCoachTips(String coachTips) {
        this.coachTips = coachTips;
    }

    /**
     * @param type the type to set
     */
    public void setType(BatchCoursewareType type) {
        this.type = type;
    }

    /**
     * @param courseRound the courseRound to set
     */
    public void setCourseRound(CourseRound courseRound) {
        this.courseRound = courseRound;
    }

    /**
     * @param roundwareStatus the roundwareStatus to set
     */
    public void setRoundwareStatus(RoundwareStatus roundwareStatus) {
        this.roundwareStatus = roundwareStatus;
    }

    /**
     * @param editStatus the editStatus to set
     */
    public void setEditStatus(CoursewareEditStatus editStatus) {
        this.editStatus = editStatus;
    }

    /**
     * @param dietaryPrograms the dietaryPrograms to set
     */
    public void setDietaryPrograms(Map<String, DietaryProgram> dietaryPrograms) {
        this.dietaryPrograms = dietaryPrograms;
    }

    /**
     * @param dailyCoursewares the dailyCoursewares to set
     */
    public void setDailyCoursewares(List<DailyCourseware> dailyCoursewares) {
        this.dailyCoursewares = dailyCoursewares;
    }

    /**
     * @param disabled the disabled to set
     */
    public void setDisabled(boolean disabled) {
        this.disabled = disabled;
    }

    /**
     * @param begin the begin to set
     */
    public void setBegin(Date begin) {
        this.begin = begin;
    }

    /**
     * @param end the end to set
     */
    public void setEnd(Date end) {
        this.end = end;
    }

    /**
     * @param linkTime the linkTime to set
     */
    public void setLinkTime(Date linkTime) {
        this.linkTime = linkTime;
    }
}
